package com.magenta.maxoptra.gis.commons;

import java.io.*;
import java.util.*;
import java.util.regex.Pattern;

/**
 * Created by IntelliJ IDEA.
 * User: Sychin
 * Date: 21.10.2008
 * Time: 13:37:37
 */
public class StringUtils {
    private static final String NEXT_LINE = "\n";

    public static String capitalize(String inputWord) {
        return inputWord.substring(0, 1).toUpperCase() + inputWord.substring(1).toLowerCase();
    }

    public static Boolean isEmpty(String s) {
        return s == null || s.trim().isEmpty();
    }

    public static Boolean isNotEmpty(String s) {
        return !isEmpty(s);
    }

    public static String getSplittedPart(String source, int part, int partSize) {
        int leftRange = (part - 1) * partSize + partSize;
        return source.substring((part - 1) * partSize, (source.length() > leftRange) ? leftRange : source.length());
    }

    public static int getSplittedPartCount(String source, int partSize) {
        return source.length() / partSize + 1;
    }

    public static String join(Collection s, String delimiter) {
        if (s.isEmpty()) {
            return "";
        }
        Iterator iter = s.iterator();
        StringBuffer buffer = new StringBuffer(iter.next().toString());
        while (iter.hasNext()) {
            buffer.append(delimiter).append(iter.next());
        }
        return buffer.toString();
    }

    //DateTimeZone tz, DateTimeFormatter fmt
    public static String translate(String text, Map<String, String> wordPair, TimeZone tz, String fmt) {
//        //1. Search by regexp for substrings in braces "\<(.*\)>" and indices of their entering in the string
//        //2. Search for translations of these substrings in the map
//        //3. Replace substrings with translations at found indices
//        String translated = text;
//        if (text != null && wordPair != null) {
//            for (Map.Entry<String, String> pair : wordPair.entrySet()) {
//                translated = translated.replaceAll(pair.getKey(), pair.getValue());
//            }
//        }
//        return translated;
        Translator td = new MsgTranslator(wordPair, null);
        td.setDateFormat(fmt);
        td.setTimeZone(tz);
        return td.translate(text);
    }

    public static String convertStreamToString(InputStream is) throws IOException {
        if (is != null) {
            StringBuilder sb = new StringBuilder();
            String line;

            try {
                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                while ((line = reader.readLine()) != null) {
                    sb.append(line).append("\n");
                }
            } finally {
                is.close();
            }
            return sb.toString();
        } else {
            return "";
        }
    }

//    public static InputStream convertStringToInputStream(String str) {
//        byte[] bytes = str.getBytes();
//        return new ByteArrayInputStream(bytes);
//    }

    public static String convertStackTraceToString(Throwable e){
        StringBuilder result = new StringBuilder();
        for (StackTraceElement stackTraceElement : e.getStackTrace()) {
            result.append(stackTraceElement.toString()).
                    append(NEXT_LINE);
        }
        return result.toString();
    }

    public static String cutLastSymbols(String str, int symbolsCount) {
        if (symbolsCount < str.length() && symbolsCount > 0) {
            return str.substring(0, str.length() - symbolsCount);
        }
        return str;
    }

    public static String toString(String[] array, String delimiter) {
        String result = "";
        for (String s : array) {
            result += s + delimiter;
        }
        return result;
    }

    public static String toString(List<String[]> array, String cellDelimiter, String rowDelimiter) {
        String result = "";
        for (String[] s : array) {
            result += toString(s, cellDelimiter) + rowDelimiter;
        }
        return result;
    }

    public static String prepareForIn(String... array) {
        String result = "";
        for (String s : array) {
            result += "'" + s + "'" + ", ";
        }
        return StringUtils.cutLastSymbols(result, 2);
    }

    public static String trim(String s) {
        return (s != null ? s.trim() : null);
    }

    static final Pattern maxoptraClasses = Pattern.compile("^com.magenta.maxoptra.*");

    /**
     * Provide additional debug info if available with throwable message.
     * @param throwable
     * @return simple text without formating.
     */
    public static String formatThrowMessage(Throwable throwable) {
        StringBuilder msg = new StringBuilder();
        //TYPE THROABLE INFO
        msg.append(throwable.getClass().getName());
        StackTraceElement[] stackTrace = throwable.getStackTrace();
        //IF DEBUG INFO AVAILABLE
        if (stackTrace.length > 0) {
            msg.append('[');

            int maxoptraStackPosition = discoverCodePoint(stackTrace);
            if (maxoptraStackPosition > 0) {
                appendStackTraceElement(msg, stackTrace[maxoptraStackPosition]);
                msg.append('-').append('>');
            }
            appendStackTraceElement(msg, stackTrace[0]);
            msg.append(']');
        }
        msg.append(':');
        String msgBody = throwable.getLocalizedMessage();
        if (msgBody != null) {
            msg.append(msgBody);
        }
        return msg.toString();
    }

    private static void appendStackTraceElement(StringBuilder msg,
                                                StackTraceElement stackTraceElement) {
        String fileName = stackTraceElement.getFileName();
        int lineNumber = stackTraceElement.getLineNumber();
        String methodName = stackTraceElement.getMethodName();
        String className = stackTraceElement.getClassName();

        msg.append(className).append('#').append(methodName);
        if (fileName != null || lineNumber > 0) {
            msg.append('(');
            if (fileName != null) {
                msg.append(fileName);
            }
            msg.append(':').append(' ');
            if (lineNumber > 0) {
                msg.append(lineNumber);
            }
            msg.append(')');
        }
    }

    private static int discoverCodePoint(StackTraceElement[] stackTrace) {
        int i = -1;
        //FIND MAXOPTRA CODE POINT
        for (StackTraceElement traceElement : stackTrace) {
            i++;
            String className = traceElement.getClassName();
            if (maxoptraClasses.matcher(className).matches()) {
                return i;
            }
        }
        if (i < stackTrace.length) {
            return i;
        }
        return -1;
    }
}
